package com.rmb.mart.utils;

import java.awt.*;
import java.io.*;
import java.util.UUID;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.rmb.common.exception.CustomException;
import com.rmb.common.model.response.CommonCode;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;

/**
 * @Description OSS上传工具类
 * @Author wzr
 * @Date 2021-01-20 10:48
 */
public class OssUtil {

    /**
     OSS地域节点-传输加速域名（全地域上传下载加速）
     */
    private static final String ENDPOINT = "oss-accelerate.aliyuncs.com";
    /**
     公钥
     */
    private static final String ACCESS_KEY_ID = "LTAI4G4dRVRVCDE9p5Hbe8Gw";
    /**
     公钥密码
     */
    private static final String ACCESS_KEY_SECRET = "aBRtmcFcYBrXnIkrBcb71W0jRarFov";
    /**
     Bucket 域名
     */
    private static final String BUCKET_NAME = "ttoo771-oss";
    /**
     文件前缀
     */
    private static final String FILE_PREFIX = "test-";
    /**
     最大支持上传大小10MBx1024KBx1024B
     */
    private static final long FILE_MAX_SIZE = 110485760L;

    /**
     demo
     @param args 参数
     */
    public static void main (String[] args) {
        String fileName="C:\\Users\\HP\\Desktop\\上海实训高频问题题库.docx";
        File file = new File(fileName);
        String s = uploadFileInputSteam(fileName, file);
        System.out.println(s);
    }

    /**
     * 私有化构造
     */
    private OssUtil() {

    }

    /**
     * 获取图片的URL头信息
     *
     * @return 返回url头信息
     */
    private static String geturlhead() {
        //从哪个位置截取
        int cutPoint = ENDPOINT.lastIndexOf('/') + 1;
        //http头
        String head = ENDPOINT.substring(0, cutPoint);
        //服务器地址信息
        String tail = ENDPOINT.substring(cutPoint);
        //返回结果
        return head + BUCKET_NAME + "." + tail + "/";
    }

    /**
     * 获取存储在服务器上的地址
     *
     * @param oranName 文件名
     * @return 文件URL
     */
    private static String getRealName(String oranName) {
        return geturlhead() + oranName;
    }

    /**
     * 获取一个随机的文件名
     *
     * @param oranName 初始的文件名
     * @return 返回加uuid后的文件名
     */
    private static String getRandomImageName(String oranName) {
        //获取一个uuid 去掉-
        String uuid = UUID.randomUUID().toString().replace("-", "");
        //查一下是否带路径
        int cutPoint = oranName.lastIndexOf("/") + 1;
        //如果存在路径
        if (cutPoint != 0) {
            //掐头 如果开头是/ 则去掉
            String head = oranName.indexOf("/") == 0 ? oranName.substring(1, cutPoint) : oranName.substring(0, cutPoint);
            //去尾
            String tail = oranName.substring(cutPoint);
            //返回正确的带路径的图片名称
            return FILE_PREFIX + head + uuid + tail;
        }
        //不存在 直接返回
        return FILE_PREFIX + uuid + oranName;
    }

    /**
     * MultipartFile2File
     * @param multipartFile
     * @return
     */
    private static File transferToFile(MultipartFile multipartFile) {
        //选择用缓冲区来实现这个转换即使用java 创建的临时文件 使用 MultipartFile.transferto()方法 。
        File file = null;
        try {
            //获取文件名
            String originalFilename = multipartFile.getOriginalFilename();
            //获取最后一个"."的位置
            int cutPoint = originalFilename.lastIndexOf(".");
            //获取文件名
            String prefix = originalFilename.substring(0,cutPoint);
            //获取后缀名
            String suffix = originalFilename.substring(cutPoint + 1);
            //创建临时文件
            file = File.createTempFile(prefix, suffix);
            //multipartFile2file
            multipartFile.transferTo(file);
            //删除临时文件
            file.deleteOnExit();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    /**
     * 上传文件流
     *
     * @param filaPath 上传到服务器上的文件路径和名称
     * @param file         来自本地的文件或者文件流
     */
    public static String uploadFileInputSteam(String filaPath, MultipartFile file) {
        /* 通过ImageReader来解码这个file并返回一个BufferedImage对象
         * 如果找不到合适的ImageReader或者在解析过程中报错，我们可以认为这不是图片文件
         */
        try {
            Image image = ImageIO.read(file.getInputStream());
            if (image==null){
                throw new CustomException(CommonCode.INCORRECT_IMG_FORMAT);
            }
        } catch(IOException ex) {
            throw new CustomException(CommonCode.INCORRECT_IMG_FORMAT);
        }

        /*
         * 判断文件大小
         */
        long fileSize = file.getSize();
        if(fileSize>FILE_MAX_SIZE){
            throw new CustomException(CommonCode.FILE_TOO_BIG);
        }
        // <yourObjectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg
        String objectName = getRandomImageName(filaPath);

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);

        // 上传文件流
        try (InputStream inputStream = new FileInputStream(transferToFile(file))) {
            //上传到OSS
            ossClient.putObject(BUCKET_NAME, objectName, inputStream);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        // 关闭OSSClient。
        ossClient.shutdown();

        //返回文件在服务器上的全路径+名称
        return getRealName(objectName);
    }


    /**
     * 上传文件流
     *
     * @param filePath 上传到服务器上的文件路径和名称
     * @param file         来自本地的文件或者文件流
     */
    public static String uploadFileInputSteam(String filePath, File file) {

        // <yourObjectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg
        String objectName = getRandomImageName(filePath);

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);

        // 上传文件流。
        try (InputStream inputStream = new FileInputStream(file);) {
            //上传到OSS
            ossClient.putObject(BUCKET_NAME, objectName, inputStream);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        // 关闭OSSClient。
        ossClient.shutdown();

        //返回文件在服务器上的全路径+名称
        return getRealName(objectName);
    }

}
